﻿#region Creditos

/* Autor: Edilberto Sánchez Forero	*/
/* Email: esanchezfo@gmail.com		*/
/* Licencia: Propietario			*/
/* País: Colombia, Bogotá			*/

#endregion

#region Librerias

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESF.General.Entity;
using System.Runtime.Serialization;
using System.Security.Principal;
using System.Xml.Serialization;
using ESF.General;
using System.Xml;
using ESF.SSO.Core.Entities.BasicReferences;

#endregion


namespace ESF.SSO.Core.Entities
{
	[DataContract]
	[Serializable]
	public class User : Person, IIdentity
	{
		#region Constantes
		
		public const string ANONYMOUS_ALIAS = "";
		public const string ROOT_ALIAS = "root";
		
		public const string CUSTOM_AUTHENTICATIONTYPE = "ESF.SSO.Custom";
		
		#endregion
	
	
		#region Miembros
		
		[DataMember]
		public string Alias { set; get; }
		
		[DataMember]
		public string Password { set; get; }
		
		[DataMember]
		public BasicReference SecurityQuestion { set; get; }
		
		[DataMember]
		public string SecurityQuestionAnswer { set; get; }
		
		[DataMember]
		public string SessionID { set; get; }
		
		[DataMember]
		public Terminal UserTerminal { set; get; }
		
		[DataMember]
		public bool? IsEnabled { set; get; }

		[XmlIgnore]
		public bool SessionRemember { set; get; }
		
		[XmlIgnore]
		public int SessionTimeoutMinutes { set; get; }
		
		[XmlIgnore]
		public bool NotifyUserEmail { set; get; }
		
		[XmlIgnore]
		public DateTime SessionExpirationDateTime 
		{
			get
			{
				return DateTime.Now.AddMinutes (SessionTimeoutMinutes);
			}
		}

		
		public List<BasicReference> UserRights { set; get; }
		
		public List<BasicReference> UserGroups { set; get; }

		public string filFullName;

		public bool filEasySearch;

		public object filExtraValue;

		[DataMember]
		public BasicReference extEnt { set; get; }

		#endregion
		
		
		#region Constructor
		
		public User ()
		{
			Alias = ANONYMOUS_ALIAS;

			SessionID = Guid.NewGuid ().ToString ();
		}
		
		#endregion


		#region Miembros de IIdentity

		public string AuthenticationType
		{
			get { return CUSTOM_AUTHENTICATIONTYPE; }
		}

		
		public bool IsAuthenticated
		{
			get { return (Alias != ANONYMOUS_ALIAS); }
		}

		
		public string Name
		{
			get { return Alias; }
		}

		#endregion


		#region Serializacion Sencilla
		
		public string ToQuickPass()
		{
			StringBuilder stbXML;
			
			XmlWriter xmlWriter;
			
			
			stbXML = new StringBuilder ();
			
			xmlWriter = XmlWriter.Create (stbXML, new XmlWriterSettings () { OmitXmlDeclaration = true });
			
			xmlWriter.WriteStartElement ("U");
			
			xmlWriter.WriteAttributeString ("id", ID.Value.ToString ());
			xmlWriter.WriteAttributeString ("sessionID", SessionID);
			xmlWriter.WriteAttributeString ("email", Email);
			xmlWriter.WriteAttributeString ("firstName", FirstName);
			xmlWriter.WriteAttributeString ("secondName", SecondName);
			xmlWriter.WriteAttributeString ("surName", SurName);
			xmlWriter.WriteAttributeString ("lastName", LastName);
			xmlWriter.WriteAttributeString ("sessionTimeoutMinutes", SessionTimeoutMinutes.ToString ());
			
			if (Enterprise != null)
			{
				xmlWriter.WriteAttributeString("enterpriseID", Enterprise.ID.ToString ());
				xmlWriter.WriteAttributeString("enterpriseCode", Enterprise.Code);
				xmlWriter.WriteAttributeString ("enterpriseName", Enterprise.Name);
			}

			if (extEnt != null)
			{
				xmlWriter.WriteAttributeString("extEnterpriseID", extEnt.ID.ToString());
				xmlWriter.WriteAttributeString("extEnterpriseCode", extEnt.Code);
				xmlWriter.WriteAttributeString("extEnterpriseName", extEnt.Name);
			}

			if (UserGroups != null && UserGroups.Count > 0)
			{
				foreach (BasicReference ug in UserGroups)
				{
					xmlWriter.WriteStartElement ("UG");
						xmlWriter.WriteAttributeString ("code", ug.Code);
						xmlWriter.WriteAttributeString ("name", ug.Name);
					xmlWriter.WriteEndElement ();
				}
			}
			
			xmlWriter.WriteEndElement ();			
			
			xmlWriter.Close ();
			
			return stbXML.ToString ();
		}
		
		
		public static User FromQuickPass (string pCompressedSerializedValue)
		{
			XmlDocument values;
			XmlNode userXML;
			User user;
			
			
			values = new XmlDocument ();
			
			values.LoadXml (pCompressedSerializedValue);
			
			userXML = values.FirstChild;
			
			user = new User ()
			{
				ID = TextHelper.GetNullableInt (userXML.Attributes ["id"].Value),
				Email = userXML.Attributes ["email"].Value,
				FirstName = userXML.Attributes ["firstName"].Value,
				SecondName = userXML.Attributes ["secondName"].Value,
				SurName = userXML.Attributes ["surName"].Value,
				LastName = userXML.Attributes ["lastName"].Value,
				SessionID = userXML.Attributes ["sessionID"].Value,
				SessionTimeoutMinutes = int.Parse (userXML.Attributes ["sessionTimeoutMinutes"].Value)
			};

			if (userXML.Attributes ["enterpriseID"] != null)
			{
				user.Enterprise = new Enterprise ()
				{
					ID = TextHelper.GetNullableInt (userXML.Attributes ["enterpriseID"].Value),
					Code = userXML.Attributes ["enterpriseCode"].Value,
					Name = userXML.Attributes ["enterpriseName"].Value
				};
			}

			if (userXML.Attributes ["extEnterpriseID"] != null)
			{
				user.extEnt = new BasicReference ()
				{
					ID = TextHelper.GetNullableInt (userXML.Attributes ["extEnterpriseID"].Value),
					Code = userXML.Attributes ["extEnterpriseCode"].Value,
					Name = userXML.Attributes ["extEnterpriseName"].Value
				};
			}

			
			if (userXML ["UG"] != null)
			{
				user.UserGroups = new List<BasicReference> (userXML ["UG"].ChildNodes.Count);
			
				foreach (XmlNode ug in userXML ["UG"].ChildNodes)
				{
					user.UserGroups.Add (new BasicReference () { Code = ug.Attributes ["code"].Value, Name = ug.Attributes ["name"].Value });
				}
			}
			
			return user;
		}
		
		#endregion


		#region ToString

		public override string ToString()
		{
			return string.Format ("{0} ({1})", Alias, base.ToString ());
		}

		#endregion
	}
}
